package com.ecarx.vhaltests.hy11.testcases.climate;

import android.car.VehicleAreaWindow;
import android.car.hardware.CarPropertyValue;
import android.car.hardware.property.CarPropertyManager;
import android.util.Log;

import com.ecarx.vhaltests.IpcpClient;
import com.ecarx.vhaltests.VhalUnitTestBase;
import com.ecarx.xui.adaptapi.car.IWrapper;
import com.ecarx.xui.adaptapi.car.property.IProperty;

import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;

import androidx.test.platform.app.InstrumentationRegistry;


@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class HvacFuncElectricDefrosterPopTest extends VhalUnitTestBase {

    private static final String TAG = "HvacFuncElectricDefrosterPopTest";
    private static int halValue;
    private static int halStatus;

    private static int halSecondValue;
    private static int halSecondStatus;

    private static int halArea;

    private static int HVAC_FUNC_ELECTRIC_DEFROSTER_POP;


    private static final int SERVICE_ID_CLIMATE = 112;
    private static final int OP_ID_CLIMATE = 0xc8;


    final static Object lock = new Object();
    final static Object rearLock = new Object();

    protected static IWrapper wrapper;

    @BeforeClass
    public static void testInit() {
        wrapper = com.ecarx.xui.adaptapi.car.Car.createWrapper(InstrumentationRegistry.getInstrumentation().getTargetContext());
        HVAC_FUNC_ELECTRIC_DEFROSTER_POP = wrapper.getWrappedPropertyId(IWrapper.WrappedIdType.ID_TYPE_FUNCTION, IProperty.HVAC_FUNC_ELECTRIC_DEFROSTER_POP).getPropertyId();
        mCarPropertyMgr.registerCallback(carPropertyEventCallback, HVAC_FUNC_ELECTRIC_DEFROSTER_POP, CarPropertyManager.SENSOR_RATE_ONCHANGE);
        setConfig(OP_ID_CLIMATE);
        delay();
    }

    @Test
    public void testHvacFuncElectricDefrosterPopAvailable_01() {
        setHvacFuncElectricDefrosterPopAvail(1, 0);
        testHvacFuncElectricDefrosterPopAvailable(VehicleAreaWindow.WINDOW_FRONT_WINDSHIELD, true);
        delay();
    }

    @Test
    public void testHvacFuncElectricDefrosterPopAvailable_02() {
        setHvacFuncElectricDefrosterPopAvail(3, 0);
        testHvacFuncElectricDefrosterPopAvailable(VehicleAreaWindow.WINDOW_FRONT_WINDSHIELD, false);
        delay();
    }


    @Test
    public void testHvacFuncElectricDefrosterPopGet_01() {
        setHvacFuncElectricDefrosterPopAvail(1, 0);
        Assert.assertEquals(0, halValue);
        testHvacFuncElectricDefrosterPopGet(VehicleAreaWindow.WINDOW_FRONT_WINDSHIELD, 0);
        delay();
    }

    @Test
    public void testHvacFuncElectricDefrosterPopGet_02() {
        setHvacFuncElectricDefrosterPopAvail(1, 1);
        Assert.assertEquals(1, halValue);
        testHvacFuncElectricDefrosterPopGet(VehicleAreaWindow.WINDOW_FRONT_WINDSHIELD, 1);
        delay();
    }

    @Test
    public void testHvacFuncElectricDefrosterPop_Rear_Available_01() {
        setHvacFuncElectricDefrosterPopRearAvail(1, 0);
        testHvacFuncElectricDefrosterPopAvailable(VehicleAreaWindow.WINDOW_REAR_WINDSHIELD, true);
        delay();
    }

    @Test
    public void testHvacFuncElectricDefrosterPop_Rear_Available_02() {
        setHvacFuncElectricDefrosterPopRearAvail(3, 0);
        testHvacFuncElectricDefrosterPopAvailable(VehicleAreaWindow.WINDOW_REAR_WINDSHIELD, false);
        delay();
    }

    @Test
    public void testHvacFuncElectricDefrosterPop_Rear_Get_01() {
        setHvacFuncElectricDefrosterPopRearAvail(1, 0);
        Assert.assertEquals(0, halValue);
        testHvacFuncElectricDefrosterPopGet(VehicleAreaWindow.WINDOW_REAR_WINDSHIELD, 0);
        delay();
    }

    @Test
    public void testHvacFuncElectricDefrosterPop_Rear_Get_02() {
        setHvacFuncElectricDefrosterPopRearAvail(1, 1);
        Assert.assertEquals(1, halSecondValue);
        testHvacFuncElectricDefrosterPopGet(VehicleAreaWindow.WINDOW_REAR_WINDSHIELD, 1);
        delay();
    }


    private static CarPropertyManager.CarPropertyEventCallback carPropertyEventCallback = new CarPropertyManager.CarPropertyEventCallback() {
        @Override
        public void onChangeEvent(CarPropertyValue carPropertyValue) {
            try {
                halArea = carPropertyValue.getAreaId();
                Log.d(TAG, "HVAC_FUNC_ELECTRIC_DEFROSTER_POP onChangeEvent value: propertyId ：" + carPropertyValue.getPropertyId() + " propertyValue：" + carPropertyValue.getValue() + "");
                Log.d(TAG, "HVAC_FUNC_ELECTRIC_DEFROSTER_POP onChangeEvent Status：" + carPropertyValue.getStatus());
                Log.d(TAG, "HVAC_FUNC_ELECTRIC_DEFROSTER_POP onChangeEvent area：" + carPropertyValue.getAreaId());
                if (halArea == VehicleAreaWindow.WINDOW_FRONT_WINDSHIELD) {
                    halValue = (int) carPropertyValue.getValue();
                    halStatus = carPropertyValue.getStatus();
                    synchronized (lock) {
                        lock.notify();
                    }
                } else if (halArea == VehicleAreaWindow.WINDOW_REAR_WINDSHIELD) {
                    halSecondValue = (int) carPropertyValue.getValue();
                    halSecondStatus = carPropertyValue.getStatus();

                    synchronized (rearLock) {
                        rearLock.notify();
                    }
                }
                Log.d(TAG, "HVAC_FUNC_ELECTRIC_DEFROSTER_POP onChangeEvent halValue :" + halValue + " halSecondValue：" + halSecondValue);

            } catch (Exception e) {
                Log.e(TAG, e.getMessage());
            }
        }

        @Override
        public void onErrorEvent(int i, int i1) {

        }
    };


    public void lockWait() {
        try {
            synchronized (lock) {
                lock.wait(500);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void secondLockWait() {
        try {
            synchronized (rearLock) {
                rearLock.wait(500);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }


    public void testHvacFuncElectricDefrosterPopAvailable(int area, boolean avail) {
        boolean isAvail = mCarPropertyMgr.isPropertyAvailable(HVAC_FUNC_ELECTRIC_DEFROSTER_POP, area);
        Log.d(TAG, "testHvacFuncElectricDefrosterPopAvailable isAvail：" + isAvail);
        Assert.assertEquals(avail, isAvail);
    }

    public void testHvacFuncElectricDefrosterPopGet(int area, int value) {
        Log.d(TAG, "testHvacFuncElectricDefrosterPopGet area：" + area + " value: " + value);
        int isHvacFuncElectricDefrosterPop = mCarPropertyMgr.getIntProperty(HVAC_FUNC_ELECTRIC_DEFROSTER_POP, area);
        Assert.assertEquals(value, isHvacFuncElectricDefrosterPop);
    }

    public void setHvacFuncElectricDefrosterPopAvail(int avail, int popup) {
        Log.d(TAG, "setHvacFuncElectricDefrosterPopAvail avail：" + avail);
        IpcpClient ipcpClient = new IpcpClient();
        String[] config_indexs = {"paclfrntdefrostpopup.availability", "paclfrntdefrostpopup.data"};
        int[] datas = {avail, popup};
        boolean bb = ipcpClient.setClimaSignal(SERVICE_ID_CLIMATE, OP_ID_CLIMATE, config_indexs, datas);
        Assert.assertTrue(bb);
        lockWait();
    }


    public void setHvacFuncElectricDefrosterPopRearAvail(int avail, int popup) {
        Log.d(TAG, "setHvacFuncElectricDefrosterPopRearAvail avail：" + avail);
        IpcpClient ipcpClient = new IpcpClient();
        String[] config_indexs = {"paclreardefrostpopup.availability", "paclreardefrostpopup.data"};
        int[] datas = {avail, popup};
        boolean bb = ipcpClient.setClimaSignal(SERVICE_ID_CLIMATE, OP_ID_CLIMATE, config_indexs, datas);
        Assert.assertTrue(bb);
        secondLockWait();
    }


    private static void setConfig(int OperId) {
        IpcpClient ipcpClient = new IpcpClient();
        int climateOperId[] = {OperId};
        ipcpClient.setConfig(SERVICE_ID_CLIMATE, climateOperId);
    }

}
